package toolib.util;

/**
 * Copyright (c) 2008 Steffen Fielder
 */
public class MathUtil {
	
	public static final float random (float theMax) {
		return (float) Math.random () * theMax;
	}
	
	public static final float random (float theMin, float theMax) {
		return (float) Math.random () * (theMax - theMin) + theMin;
	}
	
	public static final int random (int theMax) {
		return (int) (Math.random () * (float) theMax);
	}
	
	public static final int random (int theMin, int theMax) {
		return theMin + (int) (Math.random () * (float) (theMax - theMin));
	}
	
	/**
	 * Linear interpolation between two end points of a line.
	 * 
	 * @param theStart Start point
	 * @param theStop End point
	 * @param theProgress Progress between 
	 * <code>0</code> and <code>1</code>
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float lerp (int theStart, int theStop, float theProgress) {
		return theStart + (float) (theStop - theStart) * theProgress;
	}
	
	/**
	 * Linear interpolation between two end points of a line.
	 * 
	 * @param theStart Start point
	 * @param theStop End point
	 * @param theProgress Progress between 
	 * <code>0</code> and </code>1</code>
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float lerp (float theStart, float theStop, float theProgress) {
		return theStart + (theStop - theStart) * theProgress;
	}
	
	public static final float lerpReverse (float theStart, float theStop, float theValue) {
		return (theValue - theStart) / (theStop - theStart);
	}
	
	public static final float lerpReverse (int theStart, int theStop, int theValue) {
		return (theValue - theStart) / (theStop - theStart);
	}
	
	/**
	 * Interpolation based on the power of three (cubic).
	 * 
	 * @param theStart Start value
	 * @param theStop End value
	 * @param theProgress Progress between 
	 * <code>0</code> and <code>1</code>
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float cubicIn (float theStart, float theStop, float theProgress) {
		return (theStop - theStart) * (theProgress * theProgress * theProgress) + theStart;
	}
	
	public static final float cubicInOut (float theStart, float theStop, float theProgress) {
		theProgress /= .5;
		if (theProgress < 1) {
			return (theStop - theStart) / 2 * theProgress * theProgress * theProgress + theStart;
		}else{
			return (theStop - theStart) / 2 * (float) (Math.pow (theProgress - 2, 3) + 2) + theStart;
		}
	}
	
	/**
	 * Interpolation based on the power of three (cubic).
	 * 
	 * @param theStart Start value
	 * @param theStop End value
	 * @param theProgress Progress between 
	 * <code>0</code> and <code>1</code>
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float cubicOut (float theStart, float theStop, float theProgress) {
		return (theStop - theStart) * (float) (Math.pow (theProgress - 1, 3) + 1) + theStart;
	}
	
	/**
	 * Interpolation based on the power of two (quadratic).
	 * 
	 * @param theStart Start value
	 * @param theStop End value
	 * @param theProgress Progress between 
	 * <code>0</code> and <code>1</code>.
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float quadIn (float theStart, float theStop, float theProgress) {
		return (theStop - theStart) * theProgress * theProgress + theStart;
	}
	
	public static final float quadInOut (float theStart, float theStop, float theProgress) {
		theProgress /= .5;
		if (theProgress < 1) {
			return (theStop - theStart) / 2 * theProgress * theProgress + theStart;
		}else{
			return -(theStop - theStart) / 2 * ((--theProgress) * (theProgress - 2) - 1) + theStart;
		}
	}
	
	/**
	 * Interpolation based on the power of two (quadratic).
	 * 
	 * @param theStart Start value
	 * @param theStop End value
	 * @param theProgress Progress between 
	 * <code>0</code> and <code>1</code>.
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float quadOut (float theStart, float theStop, float theProgress) {
		return -(theStop - theStart) * theProgress * (theProgress - 2) + theStart;
	}
	
	/**
	 * Interpolation based on the power of four (quartic).
	 * 
	 * @param theStart Start value
	 * @param theStop End value
	 * @param theProgress Progress between 
	 * <code>0</code> and <code>1</code>
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float quartIn (float theStart, float theStop, float theProgress) {
		return (theStop - theStart) * (theProgress * theProgress * theProgress * theProgress) + theStart;
	}
	
	public static final float quartInOut (float theStart, float theStop, float theProgress) {
		theProgress /= .5;
		if (theProgress < 1) {
			return (theStop - theStart) / 2 * theProgress * theProgress * theProgress * theProgress + theStart;
		}else{
			return -(theStop - theStart) / 2 * (float) (Math.pow (theProgress - 2, 4) - 2) + theStart;
		}
	}
	
	/**
	 * Interpolation based on the power of four (quartic).
	 * 
	 * @param theStart Start value
	 * @param theStop End value
	 * @param theProgress Progress between 
	 * <code>0</code> and <code>1</code>
	 * 
	 * @return Interpolated value for the given progress.
	 */
	public static final float quartOut (float theStart, float theStop, float theProgress) {
		return -(theStop - theStart) * (float) (Math.pow (theProgress - 1, 4) - 1) + theStart;
	}
}